package com.liuqing.www.xml解析;

import java.io.File;
import java.io.FileOutputStream;
import java.net.URLDecoder;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.dom4j.tree.DefaultAttribute;

/**http://www.w3school.com.cn/xpath/xpath_functions.asp
 * 性能很好。但在多语言方面不及dom
 * xpath语法介绍
 * nodename 选取此节点的所有子节点 <br/>
 * <xmp>
	/ 从根节点选取 <br/>
	// 从匹配选择的当前节点选择文档中的节点，而不考虑它们的位置 <br/>
	. 选取当前节点 <br/>
	.. 选取当前节点的父节点 <br/>
	@ 选取属性 
</xmp>
 * @author 
 * 
 *
 */
public class Dom4j解析 {
	public static Document doc;
	public static String path;
	public static void main(String args[]){
		getDoc("/com/liuqing/www/xml解析/resourse/student.xml");
		addNode("003","李四","女");
		modifyStudent("003","李四44");
		ReadXML();
		//writeFile();
		xpathTest();
	}
	/**
	 * /bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。 
/bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。 
/bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。 
/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 
//title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。 
//title[@lang='eng'] 选取所有 title 元素，且这些元素拥有值为 eng 的 lang 属性。 
/bookstore/book[price>35.00] 选取所有 bookstore 元素的 book 元素，且其中的 price 元素的值须大于 35.00。 
/bookstore/book[price>35.00]/title 选取所有 bookstore 元素中的 book 元素的 title 元素，且其中的 price 元素的值须大于 35.00。 
/bookstore/* 选取 bookstore 元素的所有子节点 
//* 选取文档中的所有元素 
//title[@*] 选取所有带有属性的 title 元素。 
//book/title | //book/price 选取所有 book 元素的 title 和 price 元素。 
//title | //price 选取所有文档中的 title 和 price 元素。 
/bookstore/book/title | //price 选取所有属于 bookstore 元素的 book 元素的 title 元素，以及文档中所有的 price 元素。 

	 */
	static void xpathTest(){
	//List<DefaultAttribute> li=doc.selectNodes("/students/student/@id");//得到id属性的集合
		//List <Element> li=doc.selectNodes("//student[@id]");//得到含有属性id的studett元素的集合
		//doc.selectNodes("//@id").size()//得到含有属性id的元素
	//	List <Element> li=doc.selectNodes("//student[@id='001']");//得到含有属性id且值为001或’001‘的studett元素的集合
		//List <Element> li=doc.selectNodes("/students/student[last()]");//输出003
	List <Element> li=doc.selectNodes("//student[@id!=002 and @id!=001 ]");//支持基本运算符
		//List <Element> li=doc.selectNodes("/students::");//支持基本运算符
		for(Element el:li){
			System.out.println("~~~~~~~~"+el.attributeValue("id"));	
			System.out.println("~~~~~~~~"+doc.selectNodes("/student").size());	
		}
	}
	/*
	 * 修改dom某个节点的值
	 */
	static void getDoc(String filepath){
		try {
			path=URLDecoder.decode(DOM解析.class.getResource(filepath).getFile(),"utf-8");
			SAXReader reader=new SAXReader();
			doc=reader.read(path);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/*
	 * 修改dom某个节点的值
	 */
	public static void  modifyStudent(String id,String name){
		List<Element> eles=doc.getRootElement().elements("name");
		for(Element el:eles){
			System.out.println("1xxxxxxxxxxx");	
			if(el.attributeValue("id").equals(id)){
			el.element("name").setText(name);
			}
		}
	}
	/*
	 * 修改dom某个节点的值
	 */
	static void addNode(String id,String name,String sex){
		Element elment=doc.getRootElement().addElement("student");
		elment.setAttributeValue("id", id);
		elment.addElement("name").setText(name);
		elment.addElement("sex").setText(sex);
	}
	/*
	 * 修改dom某个节点的值
	 */
	static void  ReadXML(){
		Element root=doc.getRootElement();
		List<Element> eles=root.elements();//得到子元素
		for(Element el:eles){
			System.out.println(el.getName()+" "+el.attributeValue("id"));
			List<Element> eles2=el.elements();
			for(Element el1:eles2){
				System.out.println(" "+el1.getName()+" "+el1.getText());
			}
		}
	}
	/*
	 * 修改dom某个节点的值
	 */
	static void writeFile(){
		XMLWriter writer;
		try {
			//writer = new XMLWriter(new FileWriter(new File("e:/xxoo.xml")));
			writer = new XMLWriter(new FileOutputStream(new File("e:/xxoo.xml")));
			writer.write(doc); 
			   writer.close(); 

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		   
	}
/*
 * | 计算两个节点集 //book | //cd 返回所有带有 book 和 cd 元素的节点集 
+ 加法 6 + 4 10 
- 减法 6 - 4 2 
* 乘法 6 * 4 24 
div 除法 8 div 4 2 
= 等于 price=9.80 如果 price 是 9.80，则返回 true。

如果 price 是 9.90，则返回 false。
 
!= 不等于 price!=9.80 如果 price 是 9.90，则返回 true。

如果 price 是 9.80，则返回 false。
 
< 小于 price<9.80 如果 price 是 9.00，则返回 true。

如果 price 是 9.90，则返回 false。
 
<= 小于或等于 price<=9.80 如果 price 是 9.00，则返回 true。

如果 price 是 9.90，则返回 false。
 
> 大于 price>9.80 如果 price 是 9.90，则返回 true。

如果 price 是 9.80，则返回 false。
 
>= 大于或等于 price>=9.80 如果 price 是 9.90，则返回 true。

如果 price 是 9.70，则返回 false。
 
or 或 price=9.80 or price=9.70 如果 price 是 9.80，则返回 true。

如果 price 是 9.50，则返回 false。
 
and 与 price>9.00 and price<9.90 如果 price 是 9.80，则返回 true。

如果 price 是 8.50，则返回 false。
 
mod 计算除法的余数 5 mod 2 1 

 */
}